#include "bsp_pwm.h"

static PWMInstance* PWM_Instance_List[PWM_MAX_NUM] = {NULL};
static uint8_t Idx = 0;

/**
 * @brief 中断回调函数
 * 
 * @param htim 发生中断的定时器
 */
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef* htim) 
{
    for (uint8_t i = 0; i < Idx; i ++) 
    {
        //判断是否是当前的实例
        if (htim == PWM_Instance_List[i] -> TIMx
         && NULL != PWM_Instance_List[i] -> pwm_callback
         && htim -> Channel == PWM_Instance_List[i] -> Channel) 
        {
            PWM_Instance_List[i] -> pwm_callback(PWM_Instance_List[i]);
            return;
        }
    }
}
PWMInstance* PWMInit(PWM_Init_Config_s* _config) 
{
    PWMInstance* instance = (PWMInstance*)malloc(sizeof(PWMInstance));
    memset(instance, 0, sizeof(PWMInstance));

    instance -> TIMx = _config -> TIMx;
    instance -> Channel = _config -> Channel;
    instance -> Period = _config -> Period;
    instance -> Duty_Period = _config -> Duty_Period;
    instance -> pwm_callback = _config -> pwm_callback;
    instance -> id = _config -> id;
    //instance -> Tclk = PWMSelectTclk(pwm->htim);
    HAL_TIM_PWM_Start(instance->TIMx, instance->Channel);
    PWMSetPeriod(instance, instance->Period);
    PWMSetDutyRatio(instance, instance->Duty_Period);
    PWM_Instance_List[Idx ++] = instance;
    return instance;
}

void PWMStart(PWMInstance* _instance) 
{
    HAL_TIM_PWM_Start(_instance -> TIMx, _instance -> Channel);
}

void PWMStop(PWMInstance* _instance) 
{
    HAL_TIM_PWM_Stop(_instance -> TIMx, _instance -> Channel);
}

void PWMSetDutyRatio(PWMInstance* _instance, float dutyratio) 
{
    __HAL_TIM_SetCompare(_instance -> TIMx, _instance -> Channel, 
                         dutyratio * (_instance -> TIMx -> Instance -> ARR));
}

void PWMSetPeriod(PWMInstance* _instance, float period) 
{
    __HAL_TIM_SetAutoreload(_instance -> TIMx, 
                            period*((_instance->Tclk)/(_instance->TIMx->Init.Prescaler+1)));
}
